package com.facebook.games.fa.model
{
	import mx.collections.ArrayCollection;
	
	import spark.collections.Sort;
	import spark.collections.SortField;
	
	/**
	 * Baralho
	 * @author Diego Maehler <dmaehler@gmail.com>
	 */
	[Bindable]
	public class Pack
	{
		
		public var id : int;
		
		/**
		 * Lista de cartas
		 */
		public var cards : ArrayCollection = new ArrayCollection();
		
		/**
		 * Lista das equipes
		 */
		private var teams : ArrayCollection = new ArrayCollection();
		
		/**
		 * Adiciona uma carta ao baralho caso ela não exista ainda
		 * @param card
		 * @return TRUE para carta adicionada, FALSE caso ela já existia no baralho
		 */
		public function addCard (card : Card) : Boolean
		{
			if (!this.cards.contains(card)) {
				this.cards.addItem(card);
				return true;
			} else {
				return false;
			}
		}
		
		/**
		 * Remove uma carta ao baralho
		 * @param card
		 * @return TRUE para carta removida, FALSE caso contrário
		 */
		public function removeCard (card : Card) : Boolean
		{
			if (this.cards.contains(card)) {
				this.cards.removeItemAt(this.cards.getItemIndex(card));
				return true;
			} else {
				return false;
			}
		}
		
		/**
		 * Embaralha as cartas
		 */
		public function shuffle () : void
		{
			this.prepareCards();
			this.shuffleCards();
		}
		
		/**
		 * Prepara as cartas, ordenando-as antes de embaralhar
		 */
		protected function prepareCards () : void
		{
			this.prepareTeams();
			this.orderTeams();
			this.orderAthletes();
			this.orderCards();
		}
		
		/**
		 * Prepara a lista dos times
		 */
		protected function prepareTeams () : void
		{
			
			this.teams.removeAll();
			
			for each (var card : Card in this.cards) {
				if (!this.teams.contains(card.athlete.team)) {
					this.teams.addItem(card.athlete.team);
				}
			}
			
		}
		
		/**
		 * Orderna os times das cartas em ordem alfabética
		 */
		protected function orderTeams () : void
		{
			
			this.teams.sort = new Sort();
			this.teams.sort.fields = [new SortField("name")];
			this.teams.refresh();
			
		}
		
		/**
		 * Ordena os atletas das equipes
		 */
		protected function orderAthletes () : void
		{
			for each (var team : Team in this.teams) {
				team.sortAthletes();
			}
		}
		
		/**
		 * Orderna as cartas conforme foram ordenadas as equipes e atletas.
		 */
		protected function orderCards():void
		{
			this.cards.removeAll();
			for each (var team : Team in this.teams) {
				for each (var athlete : Athlete in team.athletes) {
					this.cards.addItem(athlete.card);
				}
			}
		}
		
		/**
		 * Embaralha as cartas
		 */
		protected function shuffleCards () : void
		{
			var arr : Array = this.cards.toArray();
			
			this.cards.removeAll();
			
			while (arr.length > 0) {
				var i : int = Math.floor(Math.random() * (arr.length - 1));
				this.cards.addItemAt(arr.splice(i, 1)[0], 0); 
			}
			
		}
		
		/**
		 * Retorna se o baralho está sem cartas
		 * @return TRUE | FALSE
		 */
		public function isEmpty () : Boolean
		{
			return this.cards.length == 0;
		}
		
		/**
		 * Pega a última carta do baralho
		 * @return Card
		 */
		public function popCard () : Card
		{
			if (!this.isEmpty()) {
				const card : Card = this.cards.getItemAt(this.cards.length - 1) as Card;
				this.removeCard(card);
				return card;
			}
			return null;
		}
		
		/**
		 * Adiciona todas as cartas de um time no baralho.
		 * @param team
		 */
		public function addTeam (team : Team) : void
		{
			for each (var athlete : Athlete in team.athletes) {
				this.addCard(athlete.card);
			}
		}
		
	}
}